/*
 *  LaboratoryMain.cpp
 *  SoundController0002
 *
 *  Created by jiro on 11/04/02.
 *  Copyright 2011 jiro music. All rights reserved.
 *
 */

#include "Calclator.h"
#include "../Common/Note.h"
#include <set>
#include <map>
#include <iterator>
#include <algorithm>
#include <iostream>
#include <cmath>

using namespace sc;
using namespace std;

int main( int argc, char* argv[] )
{
	Note::Id part1[] = { Note::D, Note::AFlat };
	Note::Id part2[] = { Note::D, Note::F, Note::AFlat, Note::B };
	Note::Id part3[] = { Note::D, Note::E, Note::GFlat, Note::AFlat, Note::BFlat, Note::C };
	Note::Id part4[] = { Note::D, Note::GFlat, Note::BFlat };

	typedef std::map< std::set< Note::Id >, double > ComplexMap;
	typedef std::map< std::vector< Note::Id >, double > VectorComplexMap;
//	typedef std::multimap< double, std::set< Note::Id > > ComplexMap;
	ComplexMap complexMap;
	VectorComplexMap vectorComplexMap;
	for ( int i1 = 0; i1 < sizeof( part1 ) / sizeof( Note::Id ); i1++ ) 
	{
		for ( int i2 = 0; i2 < sizeof( part2 ) / sizeof( Note::Id ); i2++ )
		{
			for ( int i3 = 0; i3 < sizeof( part3 ) / sizeof( Note::Id ); i3++ )
			{
				for ( int i4 = 0; i4 < sizeof( part4 ) / sizeof( Note::Id ); i4++ ) {
					std::set< Note::Id > chord;
					std::vector< Note::Id > chordVector;
					chord.insert( part1[ i1 ] );
					chord.insert( part2[ i2 ] );
					chord.insert( part3[ i3 ] );
					chord.insert( part4[ i4 ] );
					chordVector.push_back( part1[ i1 ] );
					chordVector.push_back( part2[ i2 ] );
					chordVector.push_back( part3[ i3 ] );
					chordVector.push_back( part4[ i4 ] );
					double complex = Calclator::CalcComplex( chord );
					complexMap.insert( std::pair< std::set< Note::Id >, double >( chord, complex ) );
					if ( complexMap[ chord ] != complexMap.end()->second ) {
						vectorComplexMap.insert( std::pair< std::vector< Note::Id >, double >( chordVector, complex ) );
					}
				}
			}
		}
	}

	set< double > complexSet;
	for ( VectorComplexMap::iterator iter = vectorComplexMap.begin(); iter != vectorComplexMap.end(); iter++ ) {
		complexSet.insert( iter->second );
//		cout << iter->second << endl;
//		cout << Note::ToString( iter->first ) << endl;
	}
//	cout << vectorComplexMap.size() << endl;
//	copy( complexSet.begin(), complexSet.end(), ostream_iterator< double >( cout, " " ) ); 

	for ( set< double >::iterator i = complexSet.begin(); i != complexSet.end(); i++ ) {
		int complex = *i;
		cout << "complex:" << complex << endl;
		for ( ComplexMap::iterator iter = complexMap.begin(); iter != complexMap.end(); iter++ ) {
//		for ( VectorComplexMap::iterator iter = vectorComplexMap.begin(); iter != vectorComplexMap.end(); iter++ ) {
			if ( iter->second == complex ) {
				cout << Note::ToString( iter->first ) << endl;
			}
		}
	}

	return 0;
}
